use serde::{Deserialize, Serialize};
use reqwest::Client;
use crate::config::Config;

#[derive(Debug, Serialize, Deserialize)]
pub struct ModelManifest {
    pub name: String,
    pub versions: Vec<ModelVersion>,
    pub license: String,
    pub required_hardware: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ModelVersion {
    pub version: String,
    pub files: Vec<ModelFile>,
    pub dependencies: Vec<String>,
    pub sha256: String,
    pub recommended: bool,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ModelFile {
    pub name: String,
    pub size: u64,
    pub purpose: FilePurpose,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum FilePurpose {
    Model,
    Config,
    Tokenizer,
    Embedding,
}

pub async fn fetch_model_manifest(model: &str) -> Result<ModelManifest, RepoError> {
    let config = Config::load()?;
    let client = Client::new();
    let url = format!("{}{}/manifest.json", config.repository_url, model);
    
    let response = client.get(&url)
        .send()
        .await?
        .error_for_status()?;

    let manifest = response.json::<ModelManifest>().await?;
    Ok(manifest)
}

#[derive(Debug, thiserror::Error)]
pub enum RepoError {
    #[error("Repository error: {0}")]
    Reqwest(#[from] reqwest::Error),
    #[error("Configuration error: {0}")]
    Config(#[from] config::ConfigError),
}